package com.klamerek.rainbow.client.charts.geom;

public class MyIntersection {

	/**
	 * Get the first point of the intersection.
	 * @param d
	 * @param c
	 * @return
	 */
	public static MyPoint getIntersection1 (MyLine d, MyCircle c){
		return i12 (d, c, 1.0) ; 
	}

	/**
	 * Get the second point of the intersection.
	 * @param d
	 * @param c
	 * @return
	 */
	public static MyPoint getIntersection2 (MyLine d, MyCircle c){
		return i12 (d, c, -1.0) ; 
	}

	/**
	 * 
	 * @param d
	 * @param c
	 * @param signe
	 * @return
	 */
	private static MyPoint i12 (MyLine d, MyCircle c, double signe){
		double x = 0.0;
		double y = 0.0;
		if (d.getB() != 0.0) { 
			double u = d.getA() * (d.getC() + d.getB() * c.getCenter().getY()) - d.getB() * d.getB() * c.getCenter().getX() ;
			double v = d.getA() * d.getA() + d.getB() * d.getB() ;
			double w = d.getC() + d.getB() * c.getCenter().getY() ;
			double deltap = u * u - v * (d.getB() * d.getB() * (c.getCenter().getX() * c.getCenter().getX() - c.getRadius() * c.getRadius()) + w * w) ;
			if (deltap >= 0.0) {
				x = (- u + signe * Math.sqrt (deltap)) / v ;
				y = - (d.getA() * x + d.getC()) / d.getB() ; 
			}
		}else{ 
			x = - d.getC() / d.getA() ;
			double u = x - c.getCenter().getX() ;
			double v = c.getRadius() * c.getRadius() - u * u ;
			if (v >= 0.0) y = c.getCenter().getY() + signe * Math.sqrt (v) ;
		}
		return new MyPoint(x,y);
	}

	/**
	 * Get the first point of the intersection.
	 * @param c1
	 * @param c2
	 * @return
	 */
	public static MyPoint getIntersection1 (MyCircle c1, MyCircle c2){
		return icc (c1, c2, 1.0) ; 
	}

	/**
	 * Get the second point of the intersection.
	 * @param c1
	 * @param c2
	 * @return
	 */
	public static MyPoint getIntersection2 (MyCircle c1, MyCircle c2){
		return icc (c1, c2, -1.0) ; 
	}

	/**
	 * 
	 * @param c1
	 * @param c2
	 * @param signe
	 * @return
	 */
	private static MyPoint icc (MyCircle c1, MyCircle c2, double signe){
		MyPoint result = null;
		double x = 0.0;
		double y = 0.0;
		double a1 = -2.0 * c1.getCenter().getX() ; double b1 = -2.0 * c1.getCenter().getY() ;
		double a2 = -2.0 * c2.getCenter().getX() ; double b2 = -2.0 * c2.getCenter().getY() ;
		double a12 = a1 - a2 ; double b12 = b1 - b2 ;
		double a = a12 * a12 + b12 * b12 ;
		if (a != 0.0){
			double C1 = c1.getCenter().getX() * c1.getCenter().getX() + c1.getCenter().getY() * c1.getCenter().getY() - c1.getRadius() * c1.getRadius() ;
			double C2 = c2.getCenter().getX() * c2.getCenter().getX() + c2.getCenter().getY() * c2.getCenter().getY() - c2.getRadius() * c2.getRadius() ;
			double C12 = C1 - C2 ;
			double b, c;
			boolean bpga = Math.abs(b12) >= Math.abs(a12) ;
			if (bpga){
				b = 2.0 * a12 * C12 + b12 * (b1 * a2 - a1 * b2) ;
				c = C12 * C12 + b12 * (b1 * C2 - b2 * C1) ;
			}
			else{
				b = 2.0 * b12 * C12 + a12 * (a1 * b2 - b1 * a2) ;
				c = C12 * C12 + a12 * (a1 * C2 - a2 * C1) ;
			}
			double delta = b * b - 4.0 * a * c ;
			if (delta >= 0.0){
				x = -0.5 * (b + signe * Math.sqrt (delta)) / a ;
				if (bpga){
					y = - (a12 * x + C12) / b12 ;
				}else{
					y = x ; x = - (b12 * x + C12) / a12 ;
				}
				result = new MyPoint(x,y);
			}
		}
		return result;
	}

}
